package com.cy;

import com.cy.service.ConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/*我们的主启动类 使用@EnableFeignClients 注解描述是，spring工程
* 在启东市会扫描@FeignClient注解描述的接口，并基于接口创建其实现类(实现类)*/
@EnableFeignClients
@SpringBootApplication
public class NacosConsumerApplication {

    @Bean
    @LoadBalanced
    public RestTemplate loadBalancedRestTemplate(){
        return new RestTemplate();
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    private RestTemplate loadBalancedRestTemplate;
    public static void main(String[] args) {
        SpringApplication.run(NacosConsumerApplication.class, args);
    }

    @RestController
    public class ConsumerController {
        @Value("${spring.application.name}")
        private String consumerName;
        @Autowired
//        RestTemplate 可以完成消费方到提供方的调用
        private RestTemplate restTemplate;

        //        访问http://localhost:8090/consumer/doRestEcho01
        @GetMapping("/consumer/doRestEcho01")
        public String doRestEcho01() {
//            定义服务提供方的值
            String url = "http://localhost:8081/provider/echo/consumerName";
//            调用服务提供方（nacos-provider）getForObject(提供者的网址，响应数据的类型)
            return restTemplate.getForObject(url, String.class);
        }

        //        LoadBalancerClient 此对象底层基于Ribbon实现负载均衡算法 loadBalancerClient  可以帮助我们从nacos端通过服务器名字获取这个实例对象
        //loadBalancerClient 在服务器启启动后底层已经帮我们创建好了
        @Autowired
        private LoadBalancerClient loadBalancerClient;
        @Autowired
        private ConsumerService consumerService;

        @GetMapping("/consumer/doRestEcho02")
        public String doRestEcho02() {
            consumerService.doGetResoure();
//            基于服务采用一定的负载均衡算法获取服务实例  这是服务器有1个  但是有2个实例
            ServiceInstance choose = loadBalancerClient.choose("nacos-provider");
            String ip = choose.getHost();
            int port = choose.getPort();
//            轮询策略
            String url = "http://" + ip + ":" + port + "/provider/echo/consumerName";
//            假如不希望使用字符串拼接操作，看医生也如下方式（其中%s为站位符号）
//            String.format("http://%s:%s/provider/echo/%s", ip,port,consumerName);
            return restTemplate.getForObject(url, String.class);
        }

//        @GetMapping("/consumer/doRestEcho")
//        public String doRestEcho() {
//            ServiceInstance serviceInstance =
//                    loadBalancerClient.choose("nacos-provider");
//            String url = String.format("http://%s:%s/provider/echo/%s",
//                    serviceInstance.getHost(),
//                    serviceInstance.getPort(),
//                    consumerName);
//            System.out.println("request url:" + url);
//            return restTemplate.getForObject(url, String.class);
//        }

        /*@bean注解有spirng提供，通常用于描述方法，用于spring框架
         * 此方法的范围值要嫁给spring管理，类似@controller，@service @component注解
         * 这些注解一般描述的类
         * @return
         * @autowired 注解的作用？(次注解用于描述属性 或者构造方法，set方法等，用于告诉spring框架 按照一定的规则为属性进行DI操作，默认按属性、方法参数类型查找对应的对象，例如只知道一个，则直接注入，类型多个时还会按照属性名或者方法参数名进行值的注入)
         * @Bean注解的作用？一般用于配置类内部，描述相关方法，用于告诉spring此方法的返回值要交给spring管理，bean的名字默认为方法名，例如
         * */



        @GetMapping("/consumer/doRestEcho03")
        public String doRestEcho03(){
            String url="http://nacos-provider/provider/echo/"+consumerName;
            //调用服务提供方(sca-provider)
            System.out.println(url);
            return loadBalancedRestTemplate.getForObject(url,String.class);
        }
    }
}
